using StackCalc.Instructions;

namespace StackCalc.Parsing
{
	/// <summary>
	/// Takes care of trimming whitespaces.
	/// </summary>
	/// <typeparam name="TInstruction">The type of the instruction.</typeparam>
	public abstract class BaseParsingUnit<TInstruction> : IParsingUnit<TInstruction> where TInstruction : IInstruction
	{
		public bool CanParse(string input)
		{
			input = input.Trim();

			return !string.IsNullOrEmpty(input) && CanParseImplementation(input);
		}

		public bool HasSyntaxError(string input)
		{
			input = input.Trim();

			// syntax error happens if we can parse)
			return CanParse(input) && HasSyntaxErrorImplementation(input);
		}

		protected virtual bool HasSyntaxErrorImplementation(string input)
		{
			return false;
		}

		public virtual string GetErrorDescription()
		{
			// no syntax error for nearly all instances
			return "No error";
		}

		protected abstract bool CanParseImplementation(string input);

		public TInstruction Parse(string input)
		{
			input = input.Trim();

			return ParseImplementation(input);
		}

		protected abstract TInstruction ParseImplementation(string input);

		public string Trunkate(string input)
		{
			input = input.Trim();

			return TrunkateImplementation(input).Trim();
		}

		protected abstract string TrunkateImplementation(string input);
	}
}
